package com.javandad.app.server.servlet;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpSession;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.javandad.app.client.project.ProjectService;
import com.javandad.app.server.UserManager;
import com.javandad.app.server.db.DatabaseManager;
import com.javandad.app.server.db.PMFSingleton;
import com.javandad.app.shared.entity.User;
import com.javandad.app.shared.entity.project.Post;
import com.javandad.app.shared.entity.project.Project;
import com.javandad.app.shared.entity.project.ProjectAssoc;

@SuppressWarnings("serial")
public class ProjectServlet extends RemoteServiceServlet implements
		ProjectService {

	DatabaseManager dbm = DatabaseManager.getDefaultDatabaseManager();

	@Override
	public Project getProject(String projectName) {
		PersistenceManager pm = PMFSingleton.getPM();
		Project project = pm.getObjectById(Project.class, projectName);
		pm.close();
		return project;
	}

	@Override
	public List<Project> getProjects(String username, int level) {
		PersistenceManager pm = PMFSingleton.getPM();
		List<Project> projects = dbm.getAssociatedProjects(username, level, pm);
		pm.close();
		return projects;
	}

	@Override
	public List<User> getUsers(String projectname, int level) {
		PersistenceManager pm = PMFSingleton.getPM();
		Project project = pm.getObjectById(Project.class, projectname);
		List<User> users = dbm.getAssociatedUsers(project.getName(), level, pm);
		pm.close();
		return users;
	}
	
	@Override
	public List<ProjectAssoc> getProjectAssociations(String username, int level) {
		PersistenceManager pm = PMFSingleton.getPM();
		List<ProjectAssoc> assocs = dbm.getProjectAssociations(username, level, pm);
		pm.close();
		return assocs;
	}

	@Override
	public boolean createProject(String username, int level, String projectname, int type, String description, String plink, String rlink) {
		PersistenceManager pm = PMFSingleton.getPM();
		Project project = null;
		try {
			project = pm.getObjectById(Project.class, projectname);
			return false;
		} catch (JDOObjectNotFoundException e) {
			User user = dbm.getUser(username, pm);
			if (user == null)
				return false;
			project = new Project(projectname, type, description, plink, rlink);
			pm.makePersistent(project);
			ProjectAssoc ownership = new ProjectAssoc(project.getName(), user
					.getUsername(), level, new Date());
			pm.makePersistent(ownership);
			return true;
		} finally {
			pm.close();
		}
	}

	@Override
	public User getUser() {
		PersistenceManager pm = PMFSingleton.getPM();
		User user = UserManager.getCurrentUser(pm);
		pm.close();
		return user;
	}

	@Override
	public List<Post> downloadPosts(String projectName, String username,
			int level, int count) {
		List<Post> posts = (LinkedList<Post>) DatabaseManager
				.getDefaultDatabaseManager().getProjectPosts(projectName,
						username, level, count, PMFSingleton.getPM());

		return posts;
	}

	@Override
	public Post uploadPost(Post post) {
		PersistenceManager pm = PMFSingleton.getPM();
		post.setDate(new Date(System.currentTimeMillis()));
		if ((post.getUsername() == null) || (post.getUsername().isEmpty()))
			post.setUsername("Anonymous");
		Post p = pm.makePersistent(post);
		pm.close();
		return p;

	}

	@Override
	public List<String> getSessionInfo(String projectName) {
		List<String> list = new LinkedList<String>();
		HttpSession session = this.getThreadLocalRequest().getSession();
		list.add((String) session.getAttribute("mode"));
		list.add((String) session.getAttribute("username"));
		list.add(String.valueOf(isOwner(projectName, list.get(1))));

		return list;

	}

	@Override
	public boolean sendParticipationInvitation(String projectName, String username) {
		PersistenceManager pm = PMFSingleton.getPM();
		User user = DatabaseManager.getDefaultDatabaseManager().getUser(username, pm);
		if (user == null)
			return false;
		ProjectAssoc ea = DatabaseManager.getDefaultDatabaseManager().getAssociation(projectName, username, pm);
		if (ea == null) {
			ea = new ProjectAssoc(projectName, username, ProjectAssoc.PARTICIPATING_PROJECT | ProjectAssoc.FOLLOWING_PROJECT, null);
		} else if (!(ea.isParticipating() && ea.isFollowing())) {
			ea.setParticipating(true);
		} else
			return false;

		pm.makePersistent(ea);
		pm.close();
		return true;
	}

	@Override
	public ProjectAssoc getThisAssociationAmongAllIncludingUnconfirmedInvitations(
			String projectName, String username, int level) {
		PersistenceManager pm = PMFSingleton.getPM();
		ProjectAssoc ea = DatabaseManager.getDefaultDatabaseManager()
				.getAssociation(projectName, username, pm);
		if (ea == null || (ea.getLevel() | level) != ea.getLevel()) {
			return null;
		} else
			return ea;
	}

	@Override
	public boolean removeParticipation(String projectName, String username) {
		PersistenceManager pm = PMFSingleton.getPM();
		DatabaseManager dbm = DatabaseManager.getDefaultDatabaseManager(); 
		User user = dbm.getUser(username, pm);
		if (user == null) {
			pm.close();
			return false;
		}
		ProjectAssoc ea = dbm.getAssociation(projectName, username, pm);
		if (ea == null || !ea.isParticipating()) {
			pm.close();
			return false;
		}
		ea.setParticipating(false);
		ea.setDateBegin(null);
		pm.makePersistent(ea);
		pm.close();
		return true;
	}

	private boolean isOwner(String projectName, String username) {
		PersistenceManager pm = PMFSingleton.getPM();
		ProjectAssoc pa = DatabaseManager.getDefaultDatabaseManager()
				.getAssociation(projectName, username, pm);
		pm.close();
		if (pa != null && pa.isOwner())
			return true;
		else
			return false;

	}

	@Override
	public boolean followProject(String projectName, String username,
			boolean what) {
		PersistenceManager pm = PMFSingleton.getPM();
		ProjectAssoc pa = DatabaseManager.getDefaultDatabaseManager()
				.getAssociation(projectName, username, pm);
		if (pa == null) {
			if (what){
				pa = new ProjectAssoc(projectName, username,
						ProjectAssoc.FOLLOWING_PROJECT, null);
				
			}else{
				return true;
			}
		} else {
			if(pa.isFollowing() == what)
				return true;
			else
				pa.setFollowing(what);
		}
		pm.makePersistent(pa);
		pm.close();
		return true;

	}

}
